home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / c / blit.zip / BLIT.ASM next >
Assembly Source File  |  1988-02-21  |  24KB  |  1,071 lines

  1. _DATA    segment    word public 'DATA'
  2.  
  3.     include    blit.def
  4.  
  5. count_begin    macro
  6. thisone    =    $
  7.     dw    ?
  8.     endm
  9.  
  10. count_end    macro    a
  11.   ifdif <a>,<>
  12.     org    $-a
  13.   endif
  14. thatone    =    $
  15.     org    thisone
  16.     dw    thatone-thisone-2
  17.     org    thatone
  18.     endm
  19.  
  20. ;note that the two words previous to the given verb must be the offsets
  21. ;  (in the data segment!) of two routines.  The first (cs:put_byte_subr-4) is
  22. ;  a routine that puts the byte in al with a mask of 0ffh.  The second
  23. ;  (cs:put_byte_subr-2) is a routine that puts the byte in al using the mask
  24. ;  in dl.
  25.  
  26. put_byte_subr    dw    ?        ;our transfer mode.
  27.  
  28. count        dw    ?
  29.  
  30. smaller_delta    dw    ?
  31. larger_delta    dw    ?
  32. epsilon        dw    ?
  33.  
  34. new_x_size    dw    ?
  35. old_x_size    dw    ?
  36. smaller_line    dw    ?
  37. larger_line    dw    ?
  38. compression    db    ?
  39. not_compression    db    ?
  40.  
  41. bit_count    dw    ?        ;count of bits in source bitmap.
  42. line_count    dw    ?        ;count of lines in source bitmap.
  43. scan_line_count    dw    ?        ;count of lines so far done.
  44.  
  45. ;we precompute several things:
  46.  
  47. src_align    dw    ?        ;source bit alignment, 0..7
  48. src_seg        dw    ?        ;segment of source bitmap
  49. src_bytes    dw    ?        ;width of source bitmap in bytes
  50. src_left_bit    db    ?        ;leftmost bit in source bitmap
  51.  
  52. dest_align    dw    ?        ;destination bit alignment, 0..7
  53. dest_bytes    dw    ?        ;width of dest bitmap in bytes
  54. dest_left_bit    db    ?        ;leftmost bit in dest bitmap
  55.  
  56. ;this following table is used to provide shifts of differing counts.
  57. ;  On a V20, and 80x86; x=1,2,3 we could use the shift with immediate count
  58. ;  instruction, but then we're screwed on 808x processors.
  59.  
  60. get_byte_ptr    dw    ?
  61. get_ptrs    label    word
  62.     dw    0            ;shift count of zero - not used.
  63.     dw    shifted_1_get        ;special case - shift count of 1.
  64.     dw    shifted_get
  65.     dw    shifted_get
  66.     dw    shifted_get
  67.     dw    shifted_get
  68.     dw    shifted_get
  69.     dw    shifted_7_get        ;special case = shift count of -1 mod 8.
  70.  
  71. shifted_get    label    byte
  72.     count_begin
  73.     mov    ax,[si]            ;get the next two bytes.
  74.     inc    si
  75.     rol    ax,cl            ;align to screen byte.
  76.     count_end
  77.  
  78. shifted_1_get    label    byte
  79.     count_begin
  80.     mov    ax,[si]            ;get the next two bytes.
  81.     inc    si
  82.     rol    ax,1            ;align to screen byte.
  83.     count_end
  84.  
  85. shifted_7_get    label    byte
  86.     count_begin
  87.     mov    ax,[si]            ;get the next two bytes.
  88.     inc    si
  89.     xchg    ah,al            ;rol ax,7 == xchg ah,al;ror ax,1
  90.     ror    ax,1            ;align to screen byte.
  91.     count_end
  92.  
  93. pset_verb_1    label    byte
  94.     count_begin
  95.     stosb
  96.     count_end
  97. pset_verb_2    label    byte
  98.     count_begin
  99.     xor    al,es:[di]
  100.     and    al,dl
  101.     xor    es:[di],al
  102.     inc    di            ;go to the next byte.
  103.     count_end
  104.  
  105. and_not_verb_1    label    byte
  106.     count_begin
  107.     not    al
  108.     and    es:[di],al
  109.     inc    di            ;go to the next byte.
  110.     count_end
  111. and_not_verb_2    label    byte
  112.     count_begin
  113.     not    al
  114.     not    dl
  115.     or    al,dl
  116.     and    es:[di],al
  117.     inc    di            ;go to the next byte.
  118.     count_end
  119.  
  120. preset_verb_1    label    byte
  121.     count_begin
  122.     not    al
  123.     stosb
  124.     count_end
  125. preset_verb_2    label    byte
  126.     count_begin
  127.     not    al
  128.     xor    al,es:[di]
  129.     and    al,dl
  130.     xor    es:[di],al
  131.     inc    di            ;go to the next byte.
  132.     count_end
  133.  
  134. and_verb_1    label    byte
  135.     count_begin
  136.     and    es:[di],al
  137.     inc    di            ;go to the next byte.
  138.     count_end
  139. and_verb_2    label    byte
  140.     count_begin
  141.     not    dl
  142.     or    al,dl
  143.     and    es:[di],al
  144.     inc    di            ;go to the next byte.
  145.     count_end
  146.  
  147. or_verb_1    label    byte
  148.     count_begin
  149.     or    es:[di],al
  150.     inc    di            ;go to the next byte.
  151.     count_end
  152. or_verb_2    label    byte
  153.     count_begin
  154.     and    al,dl            ;only set the bits given in al.
  155.     or    es:[di],al
  156.     inc    di            ;go to the next byte.
  157.     count_end
  158.  
  159. or_not_verb_1    label    byte
  160.     count_begin
  161.     not    al
  162.     or    es:[di],al
  163.     inc    di            ;go to the next byte.
  164.     count_end
  165. or_not_verb_2    label    byte
  166.     count_begin
  167.     not    al
  168.     and    al,dl            ;only set the bits given in al.
  169.     or    es:[di],al
  170.     inc    di            ;go to the next byte.
  171.     count_end
  172.  
  173. xor_verb_1    label    byte
  174.     count_begin
  175.     xor    es:[di],al
  176.     inc    di            ;go to the next byte.
  177.     count_end
  178. xor_verb_2    label    byte
  179.     count_begin
  180.     and    al,dl            ;only xor the bits given in al.
  181.     xor    es:[di],al
  182.     inc    di            ;go to the next byte.
  183.     count_end
  184.  
  185. _DATA    ends
  186.  
  187. _TEXT    segment    byte public 'CODE'
  188.     assume    cs:_TEXT, ds:_DATA, ss:_DATA
  189.  
  190. put_sized:
  191.     mov    compression,1        ;assume we're compressing zeroes.
  192.     mov    not_compression,0
  193.     cmp    put_byte_subr,offset _pset_verb
  194.     jne    put_sized_1
  195.     mov    compression,-1        ;we're compressing ones
  196.     mov    not_compression,1
  197. put_sized_1:
  198.  
  199.     mov    ax,bit_count
  200.     mov    old_x_size,ax        ;remember the old h size.
  201.  
  202.     mov    cx,src_align        ;compute the src left bit.
  203.     mov    al,80h
  204.     shr    al,cl
  205.     mov    src_left_bit,al
  206.  
  207.     mov    ax,[di].right        ;compute the new h size.
  208.     sub    ax,[di].left
  209.     mov    new_x_size,ax        ;remember the new h size.
  210.  
  211.     mov    dest_align,bp        ;compute the dest left bit.
  212.     mov    cx,bp
  213.     mov    al,80h
  214.     shr    al,cl
  215.     mov    dest_left_bit,al
  216.  
  217.     mov    ax,[di].bot        ;compute the new v size.
  218.     sub    ax,[di].top
  219.  
  220.     cmp    ax,line_count        ;which is larger?
  221.     jb    put_shrink_1        ;go if we're shrinking
  222. ;expand it here.  We have more lines in the dest than the source.
  223.     mov    bx,line_count        ;don't include the last scan line.
  224.     mov    smaller_delta,bx
  225.  
  226.     mov    larger_delta,ax
  227.     mov    line_count,ax
  228.     mov    epsilon,0
  229.  
  230.     call    blit_setup
  231.     mov    src_seg,ax
  232.  
  233.     mov    bx,src_bytes
  234.     mov    scan_line_count,bx
  235. put_expand_2:
  236.     push    si
  237.     push    di
  238.     call    put_sized_line
  239.     pop    di
  240.     pop    si
  241.  
  242.     mov    bx,epsilon
  243.     mov    dx,larger_delta
  244.     add    bx,smaller_delta
  245.     cmp    bx,dx            ;past the larger yet?
  246.     jl    put_expand_3        ;no.
  247.     sub    bx,dx            ;yes - subtract it.
  248.     add    si,src_bytes        ;advance to next line.
  249. put_expand_3:
  250.     mov    epsilon,bx
  251.  
  252.     add    di,dest_bytes
  253.     dec    line_count
  254.     jne    put_expand_2
  255.     ret
  256.  
  257. put_shrink_1:
  258. ;shrink it here.  We have more lines in the source than in the dest.
  259.     mov    smaller_delta,ax
  260.  
  261.     mov    ax,line_count
  262.     mov    larger_delta,ax
  263.     mov    epsilon,0
  264.  
  265.     call    blit_setup
  266.     mov    src_seg,ax
  267.  
  268.     mov    scan_line_count,0
  269.  
  270. put_shrink_2:
  271.     mov    bx,src_bytes
  272.     add    scan_line_count,bx    ;include another scan line in the processing.
  273.  
  274.     mov    bx,epsilon
  275.     mov    dx,larger_delta
  276.     add    bx,smaller_delta
  277.     mov    epsilon,bx
  278.     cmp    bx,dx            ;past the larger yet?
  279.     jl    put_shrink_3        ;no.
  280.     sub    bx,dx            ;yes - subtract it off.
  281.     mov    epsilon,bx
  282.  
  283.     push    si
  284.     push    di
  285.     call    put_sized_line
  286.     pop    di
  287.     pop    si
  288.  
  289.     add    si,scan_line_count    ;move the source down a line.
  290.     mov    scan_line_count,0
  291.  
  292.     add    di,dest_bytes        ;move to the next line.
  293.  
  294. put_shrink_3:
  295.     dec    line_count
  296.     jne    put_shrink_2
  297.     ret
  298.  
  299.  
  300. put_sized_line:
  301. ;ds:si->array, es:di->screen, bp=destination alignment,
  302. ;  scan_line_count=number of scan lines to process.
  303. ;don't destroy bp.
  304.  
  305.     mov    ax,new_x_size        ;are we changing the x size?
  306.     cmp    ax,old_x_size
  307.     jb    put_smaller_line    ;yes - it's shorter.
  308.     ja    put_larger_line        ;yes - it's longer.
  309.     mov    bx,ax
  310.     mov    bp,dest_align        ;get the destination alignment.
  311.     jmp    put_scan_line        ;no - same size.
  312.  
  313. put_larger_line:
  314.     mov    larger_line,ax        ;new is larger.
  315.     mov    bit_count,ax
  316.     xor    bx,bx
  317.  
  318.     mov    ax,old_x_size
  319.     mov    smaller_line,ax
  320.  
  321.     mov    dl,dest_left_bit
  322.     mov    dh,src_left_bit        ;dh=source mask.
  323.  
  324.     mov    cx,bit_count
  325.  
  326.     push    ds
  327.     mov    ds,src_seg
  328.     assume    ds:nothing
  329.  
  330.     mov    ah,[si]            ;get the first source byte.
  331.     inc    si
  332. put_larger_line_1:
  333.  
  334.     xor    al,al
  335.     test    dh,ah            ;is the source bit set?
  336.     je    put_larger_line_2    ;no.
  337.     mov    al,dl            ;yes - get the dest bit in question.
  338. put_larger_line_2:
  339.     call    put_byte_subr        ;put this byte.
  340.  
  341.     add    bx,smaller_line
  342.     cmp    bx,larger_line
  343.     jb    put_larger_line_3
  344.     sub    bx,larger_line
  345.  
  346.     ror    dh,1            ;move over a source bit.
  347.     jnc    put_larger_line_3
  348.     mov    ah,[si]
  349.     inc    si
  350. put_larger_line_3:
  351.  
  352.     ror    dl,1            ;move over a dest bit.
  353.     adc    di,0            ;if cy, move over in di.
  354.     loop    put_larger_line_1    ;no.
  355.  
  356.     cmp    dh,80h            ;did we use any of the source bits?
  357.     jne    put_larger_line_5
  358.     dec    si            ;no - backup.
  359. put_larger_line_5:
  360.     pop    ds
  361.     assume    ds:_DATA
  362.     ret
  363.  
  364.  
  365. put_smaller_line:
  366.     mov    smaller_line,ax
  367.  
  368.     mov    ax,old_x_size
  369.     mov    larger_line,ax
  370.     mov    bit_count,ax
  371.     xor    bx,bx
  372.  
  373.     mov    cx,bit_count
  374.  
  375.     mov    dl,dest_left_bit
  376.     mov    dh,src_left_bit        ;dh=source mask.
  377.  
  378.     push    ds
  379.     mov    ds,src_seg
  380.     assume    ds:nothing
  381.  
  382.     mov    ah,7fh            ;init the sampling sum.
  383. put_smaller_line_1:
  384.  
  385.     push    bx
  386.  
  387.     mov    bx,0
  388. put_smaller_line_6:
  389.     add    ah,not_compression
  390.     test    [si+bx],dh        ;is the source bit set?
  391.     je    put_smaller_line_2    ;no.
  392.     add    ah,compression        ;yes - count this bit.
  393. put_smaller_line_2:
  394.     add    bx,src_bytes        ;move down a scan line.
  395.     cmp    bx,scan_line_count    ;have we